package website.digitalocean.chapter15;

import lombok.extern.slf4j.Slf4j;

import java.util.ArrayList;
import java.util.List;

/**
 * @author: longhc@citycloud.com.cn
 * @since: 2023/2/15 14:48
 * @version: 1.0
 */
@Slf4j
public class MyTopic implements Subject {

    private List<Observer> observers;
    private String message;
    private boolean changed;
    private final Object MUTEX = new Object();

    public MyTopic() {
        this.observers = new ArrayList<>();
    }

    @Override
    public void register(Observer observer) {
        if (observer == null) {
            throw new NullPointerException("observer 不可为null");
        }
        synchronized (MUTEX) {
            if (!observers.contains(observer)) {
                observers.add(observer);
            }
        }
    }

    @Override
    public void unregister(Observer observer) {
        synchronized (MUTEX) {
            observers.remove(observer);
        }
    }

    /**
     * 若已发生变更，则将事件分发给每个观察者
     */
    @Override
    public void notifyObserver() {
        synchronized (MUTEX) {
            if (!changed) {
                return;
            }
            this.changed = false;
        }
        for (Observer observer : observers) {
            // 执行通知
            observer.update();
        }
    }

    @Override
    public Object getUpdate(Observer observer) {
        return this.message;
    }

    public void postMessage(String message) {
        log.info("消息推送至主题; message:{}", message);
        this.message = message;
        this.changed = true;
        notifyObserver();
    }
}
